package com.naeeiot.calc;

import cn.hutool.core.io.FileUtil;
import com.naeeiot.calc.bean.PfcalcData;
import com.smartframework.web.core.utils.JsonUtil;

import java.io.*;
import java.util.UUID;

import static cn.hutool.core.util.CharsetUtil.GBK;

/**
 *
 * 1> 总体说明
 * 	输入模型为计算模型，每个拓扑岛一个文件，所有输入输出均为标幺值 基础功率100MVA 基础电压各自电压等级
 *
 * 2> 进程调用
 * 	netcalc -input XXXX.json -output XXXX.json  (文件为全路径名)。
 * @author LIUJUN
 */
public class PfApi {
    private String baseDir;

    public PfApi() {
        this.baseDir = System.getProperty("user.dir");
    }

    public PfApi(String baseDir) {
        this.baseDir = baseDir;
    }

    /**
     * 计算并返回结构对象
     *
     * @param pfcalcData
     * @return
     */
    public PfcalcData doCalculate(PfcalcData pfcalcData) throws Exception {
        String inputJsonFile = this.baseDir.concat(File.separator).concat(UUID.randomUUID().toString()).concat(".json");
        FileUtil.writeUtf8String(JsonUtil.getJsonByObject(pfcalcData), inputJsonFile);
        return doCalculate(inputJsonFile);
    }

    /**
     * 指定输入文件计算
     *
     * @param inputJsonFile
     * @return
     * @throws Exception
     */
    public PfcalcData doCalculate(String inputJsonFile) throws Exception {
        //TODO 以后需要检查参数完整性
        String calcResultFile = executeCalc(inputJsonFile);
        //TODO 读取返回JSON文件内容，并解析为Java对象
        PfcalcData result = JsonUtil.getBeanByJson(FileUtil.readUtf8String(calcResultFile), PfcalcData.class);
        return result;
    }

    /**
     * 输入文件计算并返回输出文件Json地址
     *
     * @param inputJsonFile
     * @return
     */
    public String executeCalc(String inputJsonFile) throws Exception {
        File file = new File(inputJsonFile);
        if (file == null || !file.exists()) {
            throw new Exception("输入文件为空或文件不存在");
        }

        String outputFile = file.getAbsolutePath().replace(file.getName(), UUID.randomUUID().toString().concat(".json"));

        String commandLinePara = String.format("netcalc -input %s -output %s", outputFile, inputJsonFile);

        this.commandExecute(commandLinePara);

        return outputFile;
    }

    /**
     * 执行命令行
     *
     * @param commandLinePara
     * @throws Exception
     */
    public void commandExecute(String commandLinePara) throws Exception {
        Runtime runtime = Runtime.getRuntime();
        try {
            Process process = runtime.exec(commandLinePara);
            InputStream errorStream = process.getErrorStream();
            InputStream inputStream = process.getInputStream();
            readStreamInfo(errorStream, inputStream);

            int ret = process.waitFor();
            process.destroy();
            if (ret == 0) {
                System.out.println("执行完成，进程退出");
            } else {
                System.out.println("程序异常退出,返回：" + ret);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("计算出错，参数：" + commandLinePara);
        }
    }

    public void readStreamInfo(InputStream... inputStreamArgs) {
        for (InputStream inputStream : inputStreamArgs) {
            new Thread(() -> {

                try {
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, GBK));
                    String output;
                    while ((output = bufferedReader.readLine()) != null) {
                        System.out.println(output);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}
